#include "http_server.h"
#include "http.h"
#include "http_session.h"
#include "servlet.h"


namespace framework
{
namespace http
{
    static framework::Logger::ptr g_logger = FRAMEWORK_LOG_NAME("system");
    
    HttpServer::HttpServer(bool keepalive
                ,framework::IOManager* worker
                ,framework::IOManager* io_worker
                ,framework::IOManager* accept_worker)
    :framework::TcpServer(worker, io_worker, accept_worker)
    ,m_isKeepalive(keepalive)
    {
        m_dispatch.reset(new ServletDispatch);

        // m_type = "http";
        // m_dispatch->addServlet("/_/status", Servlet::ptr(new StatusServlet));
        // m_dispatch->addServlet("/_/config", Servlet::ptr(new ConfigServlet));
    }

    //设置服务器名称
    void HttpServer::setName(const std::string& v)    
    {
        TcpServer::setName(v);
        // m_dispatch->setDefault(std::make_shared<NotFoundServlet>(v));
    }


    //客户端连接成功的回调函数  处理新连接的Socket类
    void HttpServer::handleClient(Socket::ptr client)
    {
        FRAMEWORK_LOG_DEBUG(g_logger) << "headleClient " << *client;
        HttpSession::ptr session(new HttpSession(client));

        while(true)
        {
            HttpRequest::ptr req = session->recvRequest(); //接收http请求
            // std::cout << *req << std::endl;
            if(!req)
            {
                FRAMEWORK_LOG_DEBUG(g_logger) << "recv http request fail, errno="
                    << errno << " errstr=" << strerror(errno)
                    << " cliet:" << *client << " keep_alive=" << m_isKeepalive;
                break;
            }

            //构造http响应类
            HttpResponse::ptr rsp(new HttpResponse(req->getVersion(), 
                req->isClose() || !m_isKeepalive));
            // rsp->setBody("hello lightning");
            // rsp->setHeader("Server", getName());
            m_dispatch->handle(req, rsp, session);
            session->sendResponse(rsp); //发送响应信息
            // std::cout << *rsp << std::endl;
            
            if(!m_isKeepalive || req->isClose()) 
            {
                break;
            }
        }

        session->close();
    }

} // namespace http
} // namespace framework